import tkinter as tk
from tkinter import ttk, messagebox
import json
import os
from encryption_utils import EncryptionUtils

class KeyManagerWindow:
    def __init__(self, parent, on_close_callback=None, force_modal=False):
        self.parent = parent
        self.on_close_callback = on_close_callback
        self.force_modal = force_modal  # 是否强制模态
        self.encryption_utils = EncryptionUtils()
        self.selected_key = self._load_selected_key()  # 当前选中的密钥名称
        self.main_app = None  # 主应用程序引用
        
        # 创建窗口
        self.window = tk.Toplevel(parent)
        self.window.title("密钥管理")
        self.window.geometry("700x500")
        self.window.minsize(600, 400)

        # 让窗口始终浮在主窗口之上
        self.window.transient(parent)
        self.window.lift()
        
        # 居中显示窗口
        self.center_window()
        
        # 创建UI
        self.create_widgets()
        
        # 加载现有密钥
        self.load_keys()
        
        # 绑定窗口关闭事件
        self.window.protocol("WM_DELETE_WINDOW", self.on_window_close)
        
        # 绑定窗口大小调整事件
        self.window.bind('<Configure>', self.on_window_resize)
        
        # 如果没有密钥且是强制模态，窗口不可关闭
        if not self.encryption_utils.key_exists() and self.force_modal:
            self.window.grab_set()  # 模态窗口，阻止用户与其他窗口交互
    
    def center_window(self):
        """将窗口居中显示"""
        self.window.update_idletasks()
        width = self.window.winfo_width()
        height = self.window.winfo_height()
        x = (self.window.winfo_screenwidth() // 2) - (width // 2)
        y = (self.window.winfo_screenheight() // 2) - (height // 2)
        self.window.geometry(f'{width}x{height}+{x}+{y}')
    
    def _load_selected_key(self):
        """加载上次选中的密钥"""
        try:
            if os.path.exists("selected_key.json"):
                with open("selected_key.json", "r", encoding="utf-8") as f:
                    data = json.load(f)
                    return data.get("selected_key", "")
            return ""
        except Exception:
            return ""
    
    def _save_selected_key(self, key_name):
        """保存选中的密钥"""
        try:
            with open("selected_key.json", "w", encoding="utf-8") as f:
                json.dump({"selected_key": key_name}, f, ensure_ascii=False, indent=2)
        except Exception:
            pass
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.window, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标题
        title_label = ttk.Label(main_frame, text="密钥管理", font=("SimHei", 16, "bold"))
        title_label.pack(pady=(0, 20))
        
        # 密钥列表框架
        list_frame = ttk.LabelFrame(main_frame, text="已保存的密钥", padding="10")
        list_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        
        # 创建Treeview来显示密钥列表
        columns = ("默认", "名称", "密钥（隐藏）")
        self.tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=8)
        
        # 设置列标题和列宽
        self.tree.heading("默认", text="默认")
        self.tree.heading("名称", text="名称")
        self.tree.heading("密钥（隐藏）", text="密钥（隐藏）")
        self.tree.column("默认", width=50, minwidth=50, anchor=tk.CENTER)
        self.tree.column("名称", width=200, minwidth=150)
        self.tree.column("密钥（隐藏）", width=350, minwidth=300)
        
        # 添加滚动条
        scrollbar_y = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.tree.yview)
        scrollbar_x = ttk.Scrollbar(list_frame, orient=tk.HORIZONTAL, command=self.tree.xview)
        self.tree.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
        
        # 布局
        self.tree.grid(row=0, column=0, sticky="nsew")
        scrollbar_y.grid(row=0, column=1, sticky="ns")
        scrollbar_x.grid(row=1, column=0, sticky="ew")
        
        # 配置网格权重
        list_frame.grid_rowconfigure(0, weight=1)
        list_frame.grid_columnconfigure(0, weight=1)
        
        # 按钮框架
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=(10, 0))
        
        # 添加密钥按钮
        add_button = ttk.Button(button_frame, text="添加密钥", command=self.add_key)
        add_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # 删除密钥按钮
        delete_button = ttk.Button(button_frame, text="删除密钥", command=self.delete_key)
        delete_button.pack(side=tk.LEFT, padx=(0, 10))
        
        # 设为默认按钮
        set_default_button = ttk.Button(button_frame, text="设为默认", command=self.set_default_key)
        set_default_button.pack(side=tk.LEFT)
        
        # 关闭按钮
        close_button = ttk.Button(button_frame, text="关闭", command=self.on_window_close)
        close_button.pack(side=tk.RIGHT)
        
        # 添加密钥表单框架
        form_frame = ttk.LabelFrame(main_frame, text="添加新密钥", padding="10")
        form_frame.pack(fill=tk.X, pady=(10, 0))
        
        # 名称输入
        name_frame = ttk.Frame(form_frame)
        name_frame.pack(fill=tk.X, pady=(0, 5))
        
        ttk.Label(name_frame, text="名称:").pack(side=tk.LEFT)
        self.name_entry = ttk.Entry(name_frame, width=30)
        self.name_entry.pack(side=tk.LEFT, padx=(10, 0))
        
        # 密钥输入
        key_frame = ttk.Frame(form_frame)
        key_frame.pack(fill=tk.X, pady=(5, 0))
        
        ttk.Label(key_frame, text="密钥:").pack(side=tk.LEFT)
        self.key_entry = ttk.Entry(key_frame, width=30, show="*")  # 隐藏输入
        self.key_entry.pack(side=tk.LEFT, padx=(10, 0))
    
    def load_keys(self):
        """加载并显示密钥列表"""
        # 清空现有项
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        # 加载密钥
        keys = self.encryption_utils.load_keys()
        
        # 添加到表格中（密钥显示为星号）
        for name, key in keys.items():
            # 确定是否为默认密钥
            is_default = "✓" if name == self.selected_key else ""
            masked_key = "*" * min(len(key), 20)  # 最多显示20个星号
            if len(key) > 20:
                masked_key += "..."
            self.tree.insert("", tk.END, values=(is_default, name, masked_key))
    
    def add_key(self):
        """添加新密钥"""
        name = self.name_entry.get().strip()
        key = self.key_entry.get().strip()
        
        if not name or not key:
            messagebox.showwarning("警告", "请填写名称和密钥")
            return
        
        # 检查名称是否已存在
        keys = self.encryption_utils.load_keys()
        if name in keys:
            if not messagebox.askyesno("确认", f"名称 '{name}' 已存在，是否覆盖？"):
                return
        
        # 添加或更新密钥
        keys[name] = key
        self.encryption_utils.save_keys(keys)
        
        # 清空输入框
        self.name_entry.delete(0, tk.END)
        self.key_entry.delete(0, tk.END)
        
        # 刷新显示
        self.load_keys()
        
        # 通知主应用程序更新密钥
        # 增加安全检查，确保self.main_app是我们期望的主应用程序对象，而不是根窗口
        if self.main_app and hasattr(self.main_app, 'update_ai_assistant_keys'):
            try:
                self.main_app.update_ai_assistant_keys()
            except Exception as e:
                print(f"通知主应用程序更新密钥时出错: {e}")
        
        # 如果之前没有密钥，现在有了就可以关闭窗口了
        if self.encryption_utils.key_exists() and self.force_modal:
            self.window.grab_release()  # 解除模态
    
    def delete_key(self):
        """删除选中的密钥"""
        selected = self.tree.selection()
        if not selected:
            messagebox.showwarning("警告", "请选择要删除的密钥")
            return
        
        # 获取选中项的名称
        item = selected[0]
        name = self.tree.item(item, "values")[1]  # 注意：现在名称在第2列
        
        # 确认删除
        if not messagebox.askyesno("确认删除", f"确定要删除密钥 '{name}' 吗？"):
            return
        
        # 删除密钥
        keys = self.encryption_utils.load_keys()
        if name in keys:
            del keys[name]
            self.encryption_utils.save_keys(keys)
            self.load_keys()
    
    def set_default_key(self):
        """设置选中的密钥为默认密钥"""
        selected = self.tree.selection()
        if not selected:
            messagebox.showwarning("警告", "请选择要设为默认的密钥")
            return
        
        # 获取选中项的名称
        item = selected[0]
        name = self.tree.item(item, "values")[1]  # 注意：现在名称在第2列
        
        # 保存选中的密钥
        self.selected_key = name
        self._save_selected_key(name)
        
        # 刷新显示
        self.load_keys()
        
        # 通知主应用程序更新密钥
        # 增加安全检查，确保self.main_app是我们期望的主应用程序对象，而不是根窗口
        if self.main_app and hasattr(self.main_app, 'update_ai_assistant_keys'):
            try:
                self.main_app.update_ai_assistant_keys()
            except Exception as e:
                print(f"通知主应用程序更新密钥时出错: {e}")
        
        messagebox.showinfo("成功", f"已将 '{name}' 设为默认密钥")
    
    def on_window_close(self):
        """窗口关闭事件处理"""
        # 直接关闭窗口
        self.window.destroy()
        if self.on_close_callback:
            self.on_close_callback()

        # 只有在强制模态模式下（自动弹出的密钥管理窗口）才关闭整个程序
        # 非强制模态模式下（手动打开的密钥管理窗口）只关闭自身
        # 但如果密钥已经配置完成（存在密钥且有选中的默认密钥），即使是自动弹出的窗口也不关闭整个程序
        if self.force_modal:
            # 检查密钥是否已经配置完成
            keys_configured = False
            try:
                encryption_utils = EncryptionUtils()
                if encryption_utils.key_exists():
                    keys = encryption_utils.load_keys()
                    if keys:
                        selected_key_exists = False
                        if os.path.exists("selected_key.json"):
                            with open("selected_key.json", "r", encoding="utf-8") as f:
                                data = json.load(f)
                                selected_key = data.get("selected_key", "")
                                if selected_key and selected_key in keys:
                                    selected_key_exists = True
                        if selected_key_exists:
                            keys_configured = True
            except Exception:
                pass
            
            # 只有在密钥未配置完成时才关闭整个程序
            if not keys_configured:
                # 退出主程序（如果父窗口仍然存在）
                try:
                    if self.parent and self.parent.winfo_exists():
                        self.parent.destroy()
                except Exception:
                    pass
    
    def on_window_resize(self, event):
        """窗口大小调整事件处理"""
        # 只处理窗口本身的调整事件，忽略子组件的调整事件
        if event.widget == self.window:
            # 可以在这里添加响应窗口大小调整的逻辑
            pass